package frog.lazy.framework.core.tools;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.EnumUtil;
import cn.hutool.core.util.ReflectUtil;
import frog.lazy.framework.core.base.IBaseEnum;

import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class BeanUtils extends BeanUtil {

    /**
     * list -> list
     * @param source  Bean对象或Map list
     * @param clazz 目标的Bean类型
     * @return Bean list
     */
    public  static <T> List<T> toBeanList(Object source, Class<T> clazz){
        List<T> tlist = new ArrayList<>();
        if(source instanceof ArrayList){
            ArrayList sources = (ArrayList) source;
            sources.stream().forEach(sou->{
                tlist.add(toBean(sou, clazz));
            });
        }
        return tlist;
    }

    /**
     *
     * @param source
     * @param clazz
     * @param <T>
     * @return source 为空时返回NULL
     */

    public static <T> T toBeanPlus(Object source, Class<T> clazz){
        if(null == source) return null;
        return toBean(source, clazz);
    }

    /**
     * 拷贝枚举类
     */
    public static  <T> T copy(Object sourceObject, Class<T> targetClass) {
        PropertyDescriptor[] targetDescriptors = BeanUtil.getPropertyDescriptors(targetClass);
        final T target = ReflectUtil.newInstance(targetClass);
        for(PropertyDescriptor descriptor : targetDescriptors) {
            Class<?> descriptorPropertyType = descriptor.getPropertyType();
            PropertyDescriptor sourceProperty = BeanUtil.getPropertyDescriptor(sourceObject.getClass(), descriptor.getName(), true);
            if(null == sourceProperty) {
                continue;
            }
            Class<?> sourcePropertyType =  sourceProperty.getPropertyType();
            Object value = BeanUtil.getFieldValue(sourceObject, descriptor.getName());
            if(null == value) {
                continue;
            }
            if(ClassUtil.isAssignable(IBaseEnum.class, sourcePropertyType) && !ClassUtil.isAssignable(IBaseEnum.class, descriptorPropertyType)) {
                IBaseEnum baseEnum = (IBaseEnum) value;
                BeanUtil.setFieldValue(target, descriptor.getName(), baseEnum.getValue());
            }else if(!ClassUtil.isAssignable(IBaseEnum.class, sourcePropertyType) && ClassUtil.isAssignable(IBaseEnum.class, descriptorPropertyType)) {
                BeanUtil.setFieldValue(target, descriptor.getName(),  EnumUtil.likeValueOf((Class<? extends Enum>)descriptorPropertyType, value));
            }else {
                BeanUtil.setFieldValue(target, descriptor.getName(), value);
            }
        }
        return target;
    }
  
}
